package com.hjq.logcat;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Sink;

public class LogcatCollectHelper {
    private static final int WHAT = 100;
    private String logcatDir = null;
    private static LogcatCollectHelper mInstance = null;
    private  LogcatListener mListener = null;
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.S");
    private SimpleDateFormat todaySimpleDataFormat = new SimpleDateFormat("yyyy-MM-dd");
    private Handler handler = null;
    private HandlerThread handlerThread = null;
    private Sink sink = null;
    private BufferedSink bufferedSink = null;

    private final Object lock = new Object();
    /** Tag 过滤规则 */
    private final List<String> mTagFilter = new ArrayList<>();
    private LogcatCollectHelper(Context context) {
        mListener = new LogcatListener();
        logcatDir = context.getCacheDir().getAbsolutePath()+File.separator+"reading_logcat/";
        Log.e("日志", "LogcatCollectHelper: path:"+logcatDir+"" );
        File file = new File(logcatDir);
        if (!file.exists()){
            try {
                file.mkdirs();
            }catch (Exception exception){
                Log.e("日志", "LogcatCollectHelper: "+exception.getMessage()+"");
            }
        }
        initFilter(context);

    }


    public static LogcatCollectHelper getInstance(Context context){
        if (mInstance == null){
            synchronized (LogcatCollectHelper.class){
                if (mInstance == null){
                    mInstance =  new LogcatCollectHelper(context);
                }
            }
        }
        return mInstance;
    }

    /**
     * 初始化 Tag 过滤器
     */
    private void initFilter(Context context) {
        try {
            mTagFilter.addAll(LogcatUtils.readTagFilter(context));
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("日志", "initFilter:  读取屏蔽配置失败" );
        }

        String[] list = context.getResources().getStringArray(R.array.logcat_filter_list);
        for (String tag : list) {
            if (tag == null || "".equals(tag)) {
                continue;
            }
            if (mTagFilter.contains(tag)) {
                continue;
            }
            mTagFilter.add(tag);
        }
    }


    public void addListener(){
        handlerThread = new HandlerThread("logcat_info");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message message) {
                if (message.what == WHAT) {
                    LogcatInfo info = (LogcatInfo) message.obj;
                    writeLogcatInfo(info);
                }
                return false;
            }
        });
        LogcatManager.start(mListener);
    }

    private void writeLogcatInfo(LogcatInfo info) {
//        Log.e("日志", "onReceiveLog: tag:"+info.getTag());

        File file = new File(logcatDir,"logcat."+todaySimpleDataFormat.format(new Date()));
        try {
            if (!file.exists()){

                file.createNewFile();
            }
            sink = Okio.sink(file);
            BufferedSink bufferedSink =  Okio.buffer(sink);
            bufferedSink.writeUtf8(info.toString()+"\n").emit();
            sink.close();
        } catch (IOException e) {
            Log.e("日志", "writeLogcatInfo: "+e.getMessage()+"" );
            e.printStackTrace();
        }


    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void removeListener(){
        LogcatManager.destroy();
        if (null != handlerThread){
            handlerThread.quitSafely();
            try {
                sink.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private class LogcatListener implements LogcatManager.Callback{

        @Override
        public void onReceiveLog(LogcatInfo info) {
        // 这个 Tag 必须不在过滤列表中，并且这个日志是当前应用打印的
            if (Integer.parseInt(info.getPid()) != android.os.Process.myPid()) {
                return;
            }
            if (!mTagFilter.contains(info.getTag())) {
                try {
                    if (handler != null) {
                        Message message = handler.obtainMessage();
                        message.what = WHAT;
                        message.obj =  info;
                        handler.sendMessage(message);
                    }
                } catch (Exception exception){
                    exception.printStackTrace();
                }

            }
        }
    }


}
